import requests
from threading import Thread
from os import system
from fake_useragent import UserAgent

#分割长度
def allocation_num(number_of_bytes, partitions):
    """
    for i in allocation_list:
        requests.get(url,headers={'Range':f'bytes={i}'})
    """
    if partitions <= 0:
        raise ValueError("partitions must be a positive number!")
    if partitions >= number_of_bytes:
        raise ValueError("partitions can not >= number_of_bytes!")
    bytes_per_partition = number_of_bytes // partitions
    allocation_list = [f"0-{bytes_per_partition}"]
    for i in range(1, partitions - 1):
        length = f"{bytes_per_partition * i + 1}-{bytes_per_partition * (i + 1)}"
        allocation_list.append(length)
    allocation_list.append(
        f"{(bytes_per_partition * (partitions - 1)) + 1}-" f"{number_of_bytes}"
    )
    return allocation_list

class threadDownload(object):
    """
    url 文件的地址

    name 用于命名

    path 下载到指定目录
    
    thread_num 线程数
    """
    def __init__(self, url, name, path, thread_num):
        self.url = url
        self.name = name
        self.path = path
        self.thread_num = thread_num
        self.res_list  = ['none' for _ in range(self.thread_num)]  # 空的response列表(笨办法)

    def download(self, Range, num):
        ua = UserAgent().random
        headers = {
            "Sec-Fetch-Dest": "image",
            "UserAgent": ua,
            "Range": f'bytes={Range}'
        }
        #按顺序把response加入到列表
        res = requests.get(self.url, headers = headers)
        if res.ok:
            self.res_list[num] = res  #加入到列表
        #判断是否请求完毕(笨办法)
        if len(self.res_list) == self.thread_num and not 'none' in self.res_list:
            #把response保存到本地
            for i in self.res_list:
                with open(f'{self.path}/{self.name}.jpg', 'ab') as f:
                    f.write(i.content)


    def Start(self):
        #取图片的长度
        ua = UserAgent().random
        headers = {
            "Sec-Fetch-Dest": "image",
            "UserAgent": ua,
        }
        byte = int(requests.head(self.url, headers = headers).headers['Content-Length'])
        #分割图片长度
        allocation_list = allocation_num(byte, self.thread_num)
        #新建一个jpg文件
        system(f'type nul>{self.path}/{self.name}.jpg')
        #开启多线程
        for i in range(len(allocation_list)):
            t = Thread(target=self.download, args=(allocation_list[i], i,))
            t.start()


if __name__ == '__main__':
    #不会翻车啦啦啦啦啦啦
    url = 'https://www.baidu.com/img/bd_logo1.png'
    a = threadDownload(url,'baidu','download',6)
    a.Start()
